package org.common.service.impl;

import org.common.service.RedisCallback;
import org.common.service.RedisService;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Transaction;
import redis.clients.jedis.exceptions.JedisException;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Set;

@Service
public class RedisServiceImpl implements RedisService {
    @Resource
    private JedisPool jedisPool;
    private Jedis jedis;

    @PostConstruct
    public void init(){
        jedis = jedisPool.getResource();
    }
    @Override
    public void execute(RedisCallback callback) {
        try {
            callback.doInRedis();
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
    }

    @Override
    // 关闭 Redis 连接
    public void close() {
        jedis.close();
    }

    @Override
    // 添加字符串类型的键值对
    public void set(String key, String value) {
        jedis.set(key, value);
    }

    @Override
    public void setWithExpire(String key, String value,long seconds) {
        jedis.setex(key,seconds,value);
    }

    @Override
    // 获取字符串类型的键值对
    public String get(String key) {
        return jedis.get(key);
    }

    @Override
    // 添加 Set 类型的键值对
    public void sadd(String key, String... members) {
        jedis.sadd(key, members);
    }

    @Override
    // 获取 Set 类型的键值对
    public Set<String> smembers(String key) {
        return jedis.smembers(key);
    }

    @Override
    // 删除键值对
    public void del(String... keys) {
        jedis.del(keys);
    }

    @Override
    // 事务
    public void execTransaction(List<String> keys, List<String> args) throws JedisException {
        Transaction transaction = jedis.multi();
        for (int i = 0; i < keys.size(); i++) {
            transaction.set(keys.get(i), args.get(i));
        }
        transaction.exec();
    }

    @Override
    // 释放分布式锁
    public boolean releaseLock(String key, String value) {
        String script = "if redis.call('get', KEYS[1]) == ARGV[1] then " +
                "return redis.call('del', KEYS[1]) " +
                "else " +
                "return 0 " +
                "end";
        Object result = jedis.eval(script, Collections.singletonList(key), Collections.singletonList(value));
        return result.equals(1L);
    }
}
